<?php
/**
 * This file is part of workerman.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the MIT-LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @author walkor<walkor@workerman.net>
 * @copyright walkor<walkor@workerman.net>
 * @link http://www.workerman.net/
 * @license http://www.opensource.org/licenses/mit-license.php MIT License
 */

/**
 * 主逻辑
 * 主要是处理 onMessage onClose 三个方法
 */
require __DIR__ . '/../../../Utils/CommonUtils.php';
use \GatewayWorker\Lib\Gateway;
use \GatewayWorker\Lib\Store;
use \GatewayWorker\Lib\Db;
use GatewayWorker\Lib\StoreDriver;
use Workerman\Lib\Timer;
use Workerman\Worker;
//require_once __DIR__ . '/../../config/Db.php';
class Events
{
    public static  $stopwordses = '';
    public static  $keyWords_Time = 0;
    public static  $auth_timer_id = 0;
//    public static $pTimeKey = 'Raylive_workman_Praise_Time';
    public static $pDataKey = 'Raylive_workman_Praise_Data';//直播缓存点赞
    public static $pDBDataKey = 'Raylive_workman_DbPraise_Data';//直播数据库点赞
    public static $LoginDBDataKey = 'Raylive_workman_DBLogin_Data';//直播数据库观看人数
    public static $LoginDataKey = 'Raylive_workman_Login_Data';//直播观看人数
    public static $rayPrefix = 'Raylive_workman';//前缀,退出房间用
    public static $viewHistoryKey = 'Raylive_View_History';//个人观看记录
    public static $giftRecordKey = 'Raylive_workman_Gift_Record';//礼物排行榜
//*******************以下为缓存的Key*******************
//    1.$pTimeKey;//每隔多久就把缓存的数据写入数据库的时间
//    2.$pDataKey;//点赞的相关数据
    
//*******************缓存的Key*******************   
    
    /**
     * 当客户端连上时触发
     * @param int $client_id
     */
    public static function onConnect($client_id)
    {
        $_SESSION['id'] = time();
//        global $mem;
//        $ret =  $mem->add(self::$viewHistoryKey, '12345');
//        echo 'workamn连接:::'.$ret.'kdjklj';
        
        // 临时给$connection对象添加一个auth_timer_id属性存储定时器id
        // 定时30秒关闭连接，需要客户端30秒内发送验证删除定时器
        self::$auth_timer_id = Timer::add(30, function()use($client_id){
            self::onClose($client_id);
        }, null, false);
        echo "连接成功!".$client_id."client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} time:".date("Y-m-d h:i:sa")."\n";
        Gateway::sendToCurrentClient('{"type":"auth","auth_key":'.$_SESSION['id'].'}');
    }
    
    public static function replace($target){
        if(!self::$stopwordses){
                echo 'stopwordses null /n';
                return $target;
        }
        foreach(self::$stopwordses as $stopwords){
                foreach (explode(',', $stopwords['words']) as $word){
                        $replace = $stopwords['rep'] == '*' ? str_repeat('*', mb_strlen($word, 'utf-8')) : $stopwords['rep'];
                        $target = str_replace($word, $replace, $target);
                }
        }
        return $target;
    }
    /**
     * 有消息时
     * @param int $client_id
     * @param string $message
     */
    public static function onMessage($client_id, $message)
    {	
        echo "onMsg开始\n";
//        $Chat_db = Db::instance('Chat_db');
        global $Chat_db;
        $Chat_db->query("set names 'utf8mb4'");
        global $mem;
//        echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']}  client_id:$client_id session:".json_encode($_SESSION)." onMessage:".$message."\n";
        echo "接受数据:client_id:".$client_id." onMessage:".$message." time:".date("Y-m-d h:i:sa")."\n";
        // 客户端传递的是json数据
        $message_data = json_decode($message, true);
        if(!$message_data)
        {
            return ;
        }
        $utiles = new App\Utils\CommonUtils();
        if(isset($message_data['live_id'])){
            $message_data['live_id'] = $utiles->getId($message_data['live_id']);
            echo "live_id:".$message_data['live_id']."\n";
        }
        if(isset($message_data['user_id'])){
            $message_data['user_id'] = $utiles->getId($message_data['user_id']);
            echo "user_id:".$message_data['user_id']."\n";
        }
        if(!isset($_SESSION['user_id'])){
            if(isset($message_data['user_id']) && $message_data['user_id'] != -1){
                $user_info= $Chat_db->select('id')->from('user')->where("id= '".$message_data['user_id']."'")->row();
                if($user_info){
                    $_SESSION['user_id'] = $user_info['id'];
                }else{
                    $_SESSION['user_id'] = '-1';
                }
            }else{
                $message_data['user_id'] = -1;
            }
        }
//        //判断是否为有效信息,type:login和relogin时,可以通过,其他必须有session的live_id即登录过
        if(!isset($_SESSION['live_id'])){
            if(($message_data['type'] != "login" && $message_data['type'] != "re_login") )
            {
                echo "非法消息,未登录!\n";
                self::onClose($client_id);
//                echo "client_ip:{$_SERVER['REMOTE_ADDR']} \$message:$message time:".date("Y-m-d h:i:sa");
                return;
            }
        }
        // 根据类型执行不同的业务
        switch($message_data['type'])
        {
            // 客户端回应服务端的心跳
            case 'ping':
                return;
            // 客户端登录 message格式: {type:login, name:xx, live_id:1} ，添加到客户端，广播给所有客户端xx进入聊天室
            case 'login':
            case 're_login':
                echo "login!\n";
                // 判断是否有房间号
                if(!isset($message_data['live_id']))
                {
                    self::onClose($client_id);
                    echo "\$message_data['live_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']} time:".date("Y-m-d h:i:sa");
                }
                if($_SESSION['id'] != $message_data['auth_key']){
                    echo "authKey错误:".$client_id." time:".date("Y-m-d h:i:sa")."\n";
                    self::onClose($client_id);
                    return ;
                }
//                // 验证成功，删除定时器，防止连接被关闭
                Timer::del(self::$auth_timer_id); 
                if(!isset($message_data['live_id']))
                {
                    self::onClose($client_id);
                    echo "\$message_data['live_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']} time:".date("Y-m-d h:i:sa");
                    return;
                }
                $live_id = $message_data['live_id'];
                $user_name = isset($message_data['user_name'])?$message_data['user_name']:"锐直播网友".intval(substr($client_id,-7));
                $_SESSION['live_id'] = $live_id;
                $_SESSION['user_name'] = $user_name;//用户名
                // 存储到当前房间的客户端列表
                $all_clients = self::addClientToRoom($live_id, $client_id, $user_name);
                // 整理客户端列表以便显示
                $client_list = self::formatClientsData($all_clients);
                $login_tt = 0;// 真实数据
                $login_total = 0; // +set数据
                //获取
                $data = self::getLiveData($_SESSION['live_id']);
                
                $client_tt = count($client_list); // 真实数据当前连接数
                $client_total =$client_tt;//
                $login_tt = $data['visit_total'];
                $login_total = $data['visit_total'] + $data['set_visit_num'];
                
                //点赞数
                $cachedata = $mem->get(self::$pDataKey);//存放lid和点赞数
                $cachePraiseNum = 0;//缓存里面的点赞数
                $dbPraiseNum = $data['praise_total'];
                if($cachedata){
                    $live_list = $cachedata['room_list'];
                    foreach ($live_list as $key=>$val){
                        if($val['live_id'] == $message_data['live_id']){
                            $cachePraiseNum = $live_list[$key]['praise_num'];
                            break;
                        }
                    }
                    //没有缓存记录为0
                }
                $praiseNum = $cachePraiseNum+$dbPraiseNum;//实际点赞数量
                
                //获取排行榜
                $topFive = self::countFive($message_data, 5, 1);
                // 转播给当前房间的所有客户端，xx进入聊天室 message {type:login, client_id:xx, name:xx} 
                $live_id = $utiles->getUuid($message_data['live_id']);
                $new_message = array( 
                                        'type'=>$message_data['type'], 
					'client_id'=>$client_id,
                                        'live_id'=>$live_id,
                                        'praise_total'=>$praiseNum,
					'user_name'=>htmlspecialchars($user_name),
//					'client_list'=>$client_list, 
                                        'gift_sort'=>$topFive, 
					'time'=>time(),
					'client_total'=>$client_total,//真实+设置连接数
					'login_total'=>$login_total,//真实+设置登入数
					'client_tt'=>$client_tt,//真实连接数
					'login_tt'=>$login_tt,//数据库数据登入
				);
                 echo "登录成功 \n";
                $client_id_array = array_keys($all_clients);
                Gateway::sendToAll(json_encode($new_message), $client_id_array);
                break;
            case 'say':
                echo "say开始\n";
                // 非法请求
                if(!isset($_SESSION['live_id']))
                {
                    self::onClose($client_id);
                    echo "\$message_data['live_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']} time:".date("Y-m-d h:i:sa");
                    return ;
                }
                if(!self::$stopwordses || time() - self::$keyWords_Time > 300) // 5分钟取一次  更新 $stopwordses
                {
                        self::$keyWords_Time = time();
                        self::$stopwordses = $Chat_db->select('words,`replace` as rep ')->from('stopwords')->where("status=1")->where("type=1")->query();	
                }	
                $live_id = $_SESSION['live_id'];
                $user_name = isset($message_data['user_name'])?$message_data['user_name']:"锐直播网友".intval(substr($client_id,-7));
                $FROM_NAME = $user_name;
                $user_type = $message_data['user_type'];
                //设备id
                if(!isset($message_data['device_id'])){
                        $message_data['device_id'] = '-1';
                }
                $message_data['content'] =  self::replace($message_data['content']);
                // 私聊
                if($message_data['to_type'] != 2)
                {
                    echo "私聊\n";
                    $insert_id = $Chat_db->insert('chat_log')
                                    ->cols(
                                            array(
                                            'cid'=>$live_id, 
                                            'type'=>'say',
                                            'to_type'=>1,//
                                            'user_type'=> $message_data['user_type'],
                                            'show_block'=> isset($message_data['show_block'])?$message_data['show_block']:'2',
                                            'from_icon'=>isset($message_data['user_icon'])?$message_data['user_icon']:'123456',
                                            'from_name'=>$user_name,
                                            'from_uid'=>$message_data['client_id'],
                                            'to_name'=>$message_data['to_user_name'], 
                                            'to_uid'=>$message_data['to_client_id'],
                                            'play_time'=>isset($message_data['play_time'])?$message_data['play_time']:'',
                                            'content'=>$message_data['content'],
//                                            'quote'=>$msg_quote,
//                                            'img'=>$msg_img,
//                                            'content_type'=> $message_data['msg_type'],
                                            'city'=>$message_data['bdCityName'],
                                            'device_id'=>$message_data['device_id'],
                                            'ip'=>$_SERVER['REMOTE_ADDR'],
                                            'updated_at'=>time(),
                                            'created_at'=>time(),	
                                            )
                                    )
                                    ->query();
                    $message_data['content'] = str_replace("msg_content_@#$!00!$#@", 'msg_content_'.$insert_id,$message_data['content']);
                    $new_message = array(
                        'msg_id'=>$insert_id,
                        'type'=>'say',
                        'userId'=>$message_data['userId'],
                        'user_name' =>$FROM_NAME,
                        'user_type'=>$message_data['user_type'],
                        'user_icon'=>$message_data['user_icon'],
                        'show_block' => isset($message_data['show_block'])?$message_data['show_block']:'3',
                        'to_type'=>$message_data['to_type'],
                        'to_client_id'=>$message_data['to_client_id'],
                        'to_user_name'=>$message_data['to_user_name'],
                        'msg_type' => $message_data['msg_type'],
                        'play_time'=>$message_data['play_time'],
                        'content'=>htmlspecialchars($message_data['content']),
//                        'img'=>isset($message_data['img'])?$message_data['img']:'' ,
//                        'video'=>isset($message_data['video'])?$message_data['video']:'' ,
//                        'msg_quote'=>$message_data['msg_quote'],
                        'bdCityName'=>$message_data['bdCityName'],
                        'bdCityCode'=>$message_data['bdCityCode'],
                        'device_id'=>$message_data['device_id'],
//                        'qiniu_host'=>$message_data['qiniu_host'],
                        'time'=>time(),
                    );
                    $row_count = $Chat_db->update('chat_log')->cols(array('content'=>$message_data['content']))->where("lid= '".$insert_id."'")->query();
                    Gateway::sendToClient($message_data['to_client_id'], json_encode($new_message));
                    $new_message['content'] = nl2br(htmlspecialchars($message_data['content']));
                    return Gateway::sendToCurrentClient(json_encode($new_message));
                }
                // 向大家说
                $all_clients = self::getClientListFromRoom($_SESSION['live_id']);
                $client_id_array = array_keys($all_clients);
                $insert_id = $Chat_db->insert('chat_log')
                            ->cols(array(
                                    'live_id'=>  isset($_SESSION['live_id'])?$_SESSION['live_id']:0, 
                                    'type'=>'say',
                                    'to_type'=>2,//all
                                    'user_type'=> isset($message_data['user_type'])?$message_data['user_type']:3,
                                    'show_block'=> isset($message_data['show_block'])?$message_data['show_block']:3,
                                    'from_uid'=>isset($message_data['user_id'])?$message_data['user_id']:'',
                                    'from_name'=>$user_name,
                                    'from_icon'=>isset($message_data['user_icon'])?$message_data['user_icon']:'',
                                    'to_name'=>isset($message_data['to_user_name'])?$message_data['to_user_name']:'', 
                                    'to_uid'=>isset($message_data['to_user_id'])?$message_data['to_user_id']:'',
                                    'play_time'=>isset($message_data['play_time'])?$message_data['play_time']:'',
                                    'img'=>'',
                                    'content'=>$message_data['content'],
                                    'city'=>isset($message_data['bdCityName'])?$message_data['bdCityName']:'',
                                    'ip'=>$_SERVER['REMOTE_ADDR'],
                                    'is_delete'=>0,
                                    'updated_at'=>time(),
                                    'created_at'=>time(),	
                                    ))->query();
                $userId = -1;
                if(isset($message_data['user_id'])){
                    if($message_data['user_id'] && $message_data['user_id']!= -1){
                        $userId = $utiles->getUuid($message_data['user_id']);
                    }
                }
                $new_message = array(
                    'msg_id'=>$insert_id,
                    'type'=>'say', 
                    'user_id'=>$userId,
                    'client_id'=>$client_id,
                    'user_name' =>$user_name,
                    'user_type'=>$message_data['user_type'],
                    'user_icon'=>isset($message_data['user_icon'])?$message_data['user_icon']:'',
                    'to_type'=>2,
                    'show_block' => isset($message_data['show_block'])?$message_data['show_block']:'2',
                    'to_client_id'=>isset($message_data['to_client_id'])?$message_data['to_client_id']:'',
                    'to_user_name'=>isset($message_data['to_user_name'])?$message_data['to_user_name']:'',
                    'msg_type' => isset($message_data['msg_type'])?$message_data['msg_type']:'',
                    'play_time'=>isset($message_data['play_time'])?$message_data['play_time']:'',
                    'content'=>htmlspecialchars($message_data['content']),
                    'bdCityName'=>isset($message_data['bdCityName'])?$message_data['bdCityName']:'',
                    'bdCityCode'=>isset($message_data['bdCityCode'])?$message_data['bdCityCode']:'',
                    'device_id'=>isset($message_data['device_id'])?$message_data['device_id']:'',
//                    'qiniu_host'=>$message_data['qiniu_host'],
                    'time'=>time(),
                );
                echo "say成功OK\n";
                Gateway::sendToAll(json_encode($new_message), $client_id_array);
                break;
            case 'set':	
                echo "set开始\n";
                    switch ($message_data['msg_type']){
                            case 'change_name': 
                                    if($message_data['user_name']){
                                            // 判断是否有房间号
                                            if(!isset($message_data['live_id']))
                                            {
                                                    throw new \Exception("\$message_data['live_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']} \$message:$message");
                                            }
                                            // 把房间号昵称放到session中
                                            $live_id = $message_data['live_id'];
                                            $user_name = htmlspecialchars($message_data['user_name']);
                                            $_SESSION['live_id'] = $live_id;
                                            $_SESSION['user_name'] = $user_name;
                                            // 存储到当前房间的客户端列表
                                            $all_clients = self::addClientToRoom($live_id, $client_id, $user_name);
                                            // 整理客户端列表以便显示
                                            $client_list = self::formatClientsData($all_clients);
                                            // 转播给当前房间的所有客户端，xx进入聊天室 message {type:login, client_id:xx, name:xx} 
                                            $new_message = array('type'=>$message_data['type'], 'msg_type'=>$message_data['msg_type'],'client_id'=>$client_id, 'user_name'=>htmlspecialchars($user_name), 'client_list'=>$client_list, 'time'=>date('m-d H:i:s'));
                                            $client_id_array = array_keys($all_clients);
                                            Gateway::sendToAll(json_encode($new_message), $client_id_array);
                                            return;
                                    }
                                    break;
                            case 'edit_msg':
                                echo "edit_msg开始\n";
                                    // 敏感词替换
                                    if(!self::$stopwordses || time() - self::$keyWords_Time > 300) // 半小时取一次  更新 $stopwordses
                                    {
                                            self::$keyWords_Time = time();
                                            self::$stopwordses = $Chat_db->select('words,`replace` as rep ')->from('stopwords')->where("status=1")->where("type=1")->query();	
                                    }	
                                    $message_data['content'] = self::replace($message_data['content']);
                                    // 把房间号昵称放到session中
                                    $live_id = $_SESSION['live_id'];
                                    $user_name = $_SESSION['user_name'];
                                    //查询出来
                                    $chat_log = $Chat_db->select('content_type,content')->from('chat_log')->where("lid= '".$message_data['msg_id']."' ")->row();
                                    echo "chat_log查询成功\n";
                                    $msg_content_after = $message_data['content'];
                                    $message_data['content'] = str_replace($message_data['msg_content_before'], $message_data['content'],$chat_log['content']);//
                                    // 更新msg
                                    $row_count = $Chat_db->update('chat_log')->cols(array('content'=>$message_data['content']))->where("id= '".$message_data['msg_id']."'")->query();
                                    echo "chat_log更新成功\n";
                                    if($row_count > 0){
                                        echo "广播\n";
                                            // 广播成功  
                                            $all_clients = self::getClientListFromRoom($_SESSION['live_id']);
                                            $client_id_array = array_keys($all_clients);
                                            $new_message = array(
                                                    'type'=>'set', 
                                                    'from_client_id'=>$client_id,
                                                    'from_user_name' =>$user_name,
                                                    'user_type'=>$message_data['user_type'],
                                                    'user_icon'=>$message_data['user_icon'],
                                                    'show_block' => isset($message_data['show_block'])?$message_data['show_block']:'2',
                                                    'to_client_id'=>'all',
                                                    'msg_type' => $message_data['msg_type'],
                                                    'msg_id'=>$message_data['msg_id'],
                                                    'content'=>htmlspecialchars($msg_content_after),
                                                    'time'=>date('m-d H:i:s'),
                                            );
                                            echo "广播成功\n";
                                            return Gateway::sendToAll(json_encode($new_message), $client_id_array);
                                    }
                                    break;
                            case 'delete_msg':
                                echo "delete_msg开始\n";
                                    // 把房间号昵称放到session中
                                    $live_id = $_SESSION['live_id'];
                                    $user_name = $_SESSION['user_name'];
                                    //删除msg
                                    $row_count = $Chat_db->update('chat_log')->cols(array('is_delete'=>'1'))->where("id= '".$message_data['msg_id']."'")->query();
                                    echo "chat_log更新成功\n";
                                    if($row_count > 0){
                                        echo "广播\n";
                                            //广播成功
                                            $all_clients = self::getClientListFromRoom($_SESSION['live_id']);
                                            $client_id_array = array_keys($all_clients);
                                            $new_message = array(
                                                    'type'=>'set', 
                                                    'from_client_id'=>$client_id,
                                                    'from_user_name' =>$user_name,
                                                    'user_type'=>$message_data['user_type'],
                                                    'user_icon'=>$message_data['user_icon'],
                                                    'show_block' => isset($message_data['show_block'])?$message_data['show_block']:'2',
                                                    'to_client_id'=>'all',
                                                    'msg_type' => $message_data['msg_type'],
                                                    'msg_id'=>$message_data['msg_id'],
        //								'content'=>nl2br(htmlspecialchars($message_data['content'])),
                                                    'time'=>time(),
                                            );
                                            echo "广播成功\n";
                                            return Gateway::sendToAll(json_encode($new_message), $client_id_array);
                                    }
                                    break;
                            case 'updateClientNum':
                                    //把房间号昵称放到session中
                                    $live_id = $_SESSION['live_id'];
                                    $user_name = $_SESSION['user_name'];
                                    // 改数据库基础人数
                                    $client_num = $message_data['setClientNum'];
                                    if(!is_numeric($client_num)){
                                            break;
                                    }
                                    //更改数据库
                                    $row_count = $Chat_db->update('live')->cols(array('set_visit_num'=>$client_num))->where("id= '".$message_data['live_id']."'")->query();//
                                    break;
                    }
                    break;
            // 视频直播点赞
            case 'praise':
                echo "prs开始\n";
                //获取数据库中数据
                $data = self::getLiveData($_SESSION['live_id']);
                
                $cachedata = $mem->get(self::$pDataKey);//存放live_id和点赞数
                
                $pNum = 0;
                if( $cachedata && $_SESSION['live_id']){
                    $live_list = $cachedata['room_list'];
//                    $user_list = $cachedata['user_list'];
                    $flag = 0;
                    foreach ($live_list as $key=>$val){
                        if($val['live_id'] == $_SESSION['live_id']){
                            $live_list[$key]['praise_num'] = $val['praise_num'] + 1;
                            $live_list[$key]['update_time'] = time();
                            $pNum = $val['praise_num'] + 1;
                            $flag = 1;
                            break;
                        }
                    }
                    if($flag == 0){
                        $val = array(
                            "live_id"=>$_SESSION['live_id'],
                            "praise_num"=>1,
                            "update_time"=>time(),
                        );
                        $pNum = 1;
                        $live_list[] = $val;
                    }
                    $cachedata['room_list'] = $live_list;
//                    //用户list
//                    $tmp_ = array(
//                        "user_id"=>$_SESSION['user_id'],
//                        "live_id"=>$_SESSION['live_id'],
//                        "update_time"=>time(),
//                    );
//                    $user_list[] = $tmp_;
//                    $cachedata['user_list'] = $user_list;
                    $mem->Replace(self::$pDataKey,$cachedata);
                }else {
//                    echo "key不存在\n";
                    $alive['live_id'] = $_SESSION['live_id'];
                    $alive['praise_num'] = 1;
                    $alive['update_time'] = time();
                    $pNum = 1;
//                    $auser['user_id'] = $_SESSION['user_id'];
//                    $auser['live_id'] = $_SESSION['live_id'];
//                    $auser['update_time'] = time();
                    $tmp_live[] = $alive;
//                    $tmp_user[] = $auser;
                    $cachedata = array(
                        'room_list' => $tmp_live,
//                        'user_list' => $tmp_user,
                    );
                    $tr = $mem->add(self::$pDataKey, $cachedata);
//                    echo "\n添加缓存成功?:".$tr."\n";
                }
//                echo "缓存数据:";
//                $tr = $mem->get(self::$pDataKey);
//                print_r($tr);
                $praise_total = $data['praise_total'] + $pNum;
                $userId = -1;
                if(isset($message_data['user_id'])){
                    if($message_data['user_id'] != -1){
                        $userId = $utiles->getUuid($message_data['user_id']);
                    }
                }
                $user_name = isset($message_data['user_name'])?$message_data['user_name']:"锐直播网友".intval(substr($client_id,-7));
                $liveId = $utiles->getUuid($message_data['live_id']);
                $new_message = array(
                    'lid'=>$liveId,
                    'type'=>'praise', 
                    'userId'=>$userId,
                    'user_name' =>$user_name,
                    'client_id'=>$client_id,
                    'to_type'=>2, 
                    'praise_total'=>$praise_total,
                    'bdCityName'=>  isset($message_data['bdCityName'])?$message_data['bdCityName']:0,
                    'bdCityCode'=>isset($message_data['bdCityCode'])?$message_data['bdCityCode']:'',
                    'device_id'=>$message_data['device_id'],
                    'time'=>time(),
                );
                echo "prs成功\n";
//                print_r($new_message);
                $all_clients = self::getClientListFromRoom($_SESSION['live_id']);
                $client_id_array = array_keys($all_clients);
                Gateway::sendToAll(json_encode($new_message), $client_id_array);
                break;
            // 主播开始\结束
            case 'start':
            case 'finish':
                echo "开始或结束\n";
                $new_message = array(
                    'type'=>$message_data['type'],
                    'from_client_id'=>$message_data['from_client_id'],
                    'time'=>time(),
                );
                $all_clients = self::getClientListFromRoom($_SESSION['live_id']);
                $client_id_array = array_keys($all_clients);
                Gateway::sendToAll(json_encode($new_message), $client_id_array);
                break;
            case 'gift':
                echo "gift 开始\n";
//                $gift= $Chat_db->select('id,gold,name,img')->from('gift')->where("id= ".$message_data['gift_id'])->row();
//                echo "送礼物 2222\n";
//                if(!$gift){
//                    echo "礼物id错误. client_ip:{$_SERVER['REMOTE_ADDR']} $message:".$message." time:".date("Y-m-d h:i:sa")."\n";
//                    return ;
//                }
//                $user= $Chat_db->select('id,gold')->from('user')->where("id= ".$message_data['user_id'])->row();
//                $gold = $user['gold'] - $gift['gold'];
//                echo "送礼物 1111\n";
//                if($gold < 0){
//                    echo "金币余额不足. client_ip:{$_SERVER['REMOTE_ADDR']} $message:".$message." time:".date("Y-m-d h:i:sa")."\n";
//                    return ;
//                }
                if($message_data['user_id'] == -1){
                    echo "用户id错误!. client_ip:{$_SERVER['REMOTE_ADDR']} time:".date("Y-m-d h:i:sa")."\n";
//                    Gateway::sendToCurrentClient('{"type":"gift","msg":"用户id错误!"}');
                    return ;
                }
                $topFive = self::countFive($message_data,5,0);
//                $live= $Chat_db->select('set_num,login_num,organization_id')->from('live')->where("cid= ".$roomId)->row();
//                $insert_id = $Chat_db->insert('gift_record')
//                            ->cols(array(
//                                    'gift_id'=>$message_data['gift_id'],
//                                    'live_id'=>$message_data['live_id'],
//                                    'user_id'=>$message_data['user_id'],
//                                    'user_icon'=>$message_data['user_icon'],
//                                    'gift_gold'=>$message_data['gold'],
//                                    'gift_time'=>$message_data['time'],
//                                    'is_delete'=>0,
//                                    'updated_at'=>time(),
//                                    'created_at'=>time(),
//                                    ))->query();
//                $row_count = $Chat_db->update('user')->cols(array('gold'=>$gold))->where("id= '".$message_data['user_id']."'")->query();
                $userId = $utiles->getUuid($message_data['user_id']);
                $liveId = $utiles->getUuid($message_data['live_id']);
                $new_message = array(
                    'lid'=>$liveId,
                    'type'=>'gift',
                    'user_id'=>$userId,
                    'user_name' =>$message_data['user_name'],
                    'user_icon'=>$message_data['user_icon'],
                    'gift_id'=>$message_data['gift_id'],
                    'gold'=>$message_data['gold'],
                    'gift_sort'=>$topFive,
                    'time'=>time(),
                );
                echo "gift成功\n";
                $all_clients = self::getClientListFromRoom($_SESSION['live_id']);
                $client_id_array = array_keys($all_clients);
                Gateway::sendToAll(json_encode($new_message), $client_id_array);
                break;
            case 'attention':
                echo "at开始\n";
                $user_name = isset($message_data['user_name'])?$message_data['user_name']:"锐直播网友".intval(substr($client_id,-7));
//                $message_data['follower_id'] = $utiles->getId($message_data['follower_id']);
//                $insert_id = $Chat_db->insert('attention')
//                            ->cols(array(
//                                    'follower_id'=>$message_data['follower_id'],
//                                    'type'=>$message_data['attention_type'],
//                                    'fans_id'=>$message_data['user_id'],
//                                    'is_delete'=>0,
//                                    'updated_at'=>time(),
//                                    'created_at'=>time(),
//                                    ))->query();
//                $followerId = $utiles->getUuid($message_data['follower_id']);
                $userId = $utiles->getUuid($message_data['user_id']);
                $liveId = $utiles->getUuid($message_data['live_id']);
                $new_message = array(
                    'live_id'=>$liveId,
                    'type'=>'attention',
                    'attention_type'=>$message_data['attention_type'],
                    'follower_id'=>$message_data['follower_id'],
                    'follower_name'=>$message_data['follower_name'],
                    'user_id'=>$userId,
                    'user_name' =>$user_name,
                    'user_icon'=>isset($message_data['user_icon'])?$message_data['user_icon']:'',
                    'time'=>time(),
                );
                echo "关注成功\n";
                $all_clients = self::getClientListFromRoom($_SESSION['live_id']);
                $client_id_array = array_keys($all_clients);
                Gateway::sendToAll(json_encode($new_message), $client_id_array);
                break;
            case 'view':
                echo "view开始\n";
                if(!isset($message_data['user_id']) || !isset($message_data['live_id']) || !isset($message_data['device_id'])){
                    echo "view参数错误. client_ip:{$_SERVER['REMOTE_ADDR']} time:".date("Y-m-d h:i:sa")."\n";
                    return ;
                }
                $cachedata = $mem->get(self::$viewHistoryKey);//观看记录
//                echo '观看历史纪录缓存';
//                print_r($cachedata);
                if( $cachedata){
                    $view_list = $cachedata['view_list'];
                    $flag = 0;
                    foreach ($view_list as $key=>$val){
                        if($val['live_id'] == $message_data['live_id'] && $val['user_id'] == $message_data['user_id']){
                            $view_list[$key]['view_time'] = $message_data['view_time'];
                            $view_list[$key]['device_id'] = $message_data['device_id'];
                            $view_list[$key]['update_time'] = time();
                            $flag = 1;
                            break;
                        }
                    }
                    if($flag == 0){
                        $val = array(
                            "user_id"=>$message_data['user_id'],
                            "live_id"=>$message_data['live_id'],
                            "view_time"=>$message_data['view_time'],
                            "device_id" => $message_data['device_id'],
                            "update_time"=>time(),
                        );
                        $view_list[] = $val;
                    }
                    $cachedata['view_list'] = $view_list;
                    $mem->Replace(self::$viewHistoryKey,$cachedata);
                }else {
//                    echo "key不存在";
                    $v['user_id'] = $message_data['user_id'];
                    $v['live_id'] = $message_data['live_id'];
                    $v['view_time'] = $message_data['view_time'];
                    $v['device_id'] = $message_data['device_id'];
                    $v['update_time'] = time();
                    $tmp_live[] = $v;
                    $cachedata = array(
                        'view_list' => $tmp_live,
                    );
                    $tr = $mem->add(self::$viewHistoryKey, $cachedata);
//                    echo "\n添加缓存成功?:".$tr."\n";
                }
                echo "观看成功\n";
                break;
        }
        echo "onMsg结束\n";
   }
   
    /**
     * 当用户断开连接时
     * @param integer $client_id 用户id
     */
    public static function onClose($client_id)
    {
        global $mem;
        global $Chat_db;
//        $Chat_db = Db::instance('Chat_db');
        // debug
        echo "断开连接:client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']}  client_id:$client_id onClose:'' time:".date("Y-m-d h:i:sa")."\n";
        // 从房间的客户端列表中删除
        if(isset($_SESSION['live_id']))
        {
            $live_id = $_SESSION['live_id'];
            self::delClientFromRoom($live_id, $client_id);
            // 广播 xxx 退出了
            if($all_clients = self::getClientListFromRoom($live_id))
            {
                $client_list = self::formatClientsData($all_clients);
                // login_num
                $login_tt = 0;// 真实数据
                $login_total = 0; // +set数据

                $client_tt = count($client_list); // 真实数据
                $client_total =$client_tt;// +set数据
                $new_message = array('type'=>'logout', 
                                    'live_id'=>$live_id, 
                                    'from_client_id'=>$client_id, 
                                    'from_user_name'=>$_SESSION['user_name'], 
                                    'client_list'=>$client_list, 
                                    'time'=>time(),
                                    'client_total'=>$client_total,
                                    'login_total'=>$login_total,
                                    'client_tt'=>$client_tt,
                                    'login_tt'=>$login_total,
                );
                $client_id_array = array_keys($all_clients);
                Gateway::sendToAll(json_encode($new_message), $client_id_array);
            }
        }
        Gateway::closeClient($client_id);
    }
    /**
    * 格式化客户端列表数据
    * @param array $all_clients
    */
    public static function formatClientsData($all_clients)
    {
        $client_list = array();
        if($all_clients)
        {
            foreach($all_clients as $tmp_client_id=>$tmp_name)
            {
                $client_list[] = array('client_id'=>$tmp_client_id, 'user_name'=>$tmp_name);
            }
        }
        return $client_list;
    }
    /**
    * 获得客户端列表
    * @todo 保存有限个
    */
    public static function getClientListFromRoom($live_id)
    {
        $key = "RAY_ROOM_CLIENT_LIST-$live_id";
        $store = Store::instance('room');
        $ret = $store->get($key);
        if(false === $ret)
        {
            if(get_class($store) == 'Memcached')
            {
                if($store->getResultCode() == \Memcached::RES_NOTFOUND)
                {
                    return array();
                }
                else 
                {
                    throw new \Exception("getClientListFromRoom($live_id)->Store::instance('room')->get($key) fail " . $store->getResultMessage());
                }
            }
            return array();
        }
        return $ret;
    }
   
    /**
     * 从客户端列表中删除一个客户端
     * @param int $client_id
     */
    public static function delClientFromRoom($live_id, $client_id)
    {
        $key = "RAY_ROOM_CLIENT_LIST-$live_id";
        $store = Store::instance('room');
        // 存储驱动是memcached
        if(get_class($store) == 'Memcached')
        {
            $cas = 0;
            $try_count = 3;
            while($try_count--)
            {
                $client_list = $store->get($key, null, $cas);
//                echo '连接客户端列表:';
//                print_r($client_list);
                if(false === $client_list)
                {
                    if($store->getResultCode() == \Memcached::RES_NOTFOUND)
                    {
                        return array();
                    }
                    else
                    {
                         throw new \Exception("Memcached->get($key) return false and memcache errcode:" .$store->getResultCode(). " errmsg:" . $store->getResultMessage());
                    }
                }
                if(isset($client_list[$client_id]))
                {
                    unset($client_list[$client_id]);
                    if($store->cas($cas, $key, $client_list))
                    {
//                        echo '删除成功后:';
//                        print_r($client_list);
                        return $client_list;
                    }
                }
                else 
                {
                    return true;
                }
            }
            throw new \Exception("delClientFromRoom($live_id, $client_id)->Store::instance('room')->cas($cas, $key, \$client_list) fail" . $store->getResultMessage());
        }
        // 存储驱动是memcache或者file
        else
        {
            $handler = fopen(__FILE__, 'r');
            flock($handler,  LOCK_EX);
            $client_list = $store->get($key);
            if(isset($client_list[$client_id]))
            {
                unset($client_list[$client_id]);
                $ret = $store->set($key, $client_list);
                flock($handler, LOCK_UN);
                return $client_list;
            }
            flock($handler, LOCK_UN);
        }
        return $client_list;
    }
    /**
     * 添加到客户端列表中
     * @param int $client_id
     * @param string $client_name
     */
    public static function addClientToRoom($live_id, $client_id, $client_name)
    {
        $key = "RAY_ROOM_CLIENT_LIST-$live_id";
        $store = Store::instance('room');
//        $store->delete($key);
        // 获取所有所有房间的实际在线客户端列表，以便将存储中不在线用户删除
        $all_online_client_id = Gateway::getOnlineStatus();
        // 存储驱动是memcached
        if(get_class($store) == 'Memcached')
        {
            $cas = 0;
            $try_count = 3;
            while($try_count--)
            {
                $client_list = $store->get($key, null, $cas);
                if(false === $client_list)
                {
                    if($store->getResultCode() == \Memcached::RES_NOTFOUND)
                    {
                        $client_list = array();
                    }
                    else
                    {
                        throw new \Exception("Memcached->get($key) return false and memcache errcode:" .$store->getResultCode(). " errmsg:" . $store->getResultMessage());
                    }
                }
                if(!isset($client_list[$client_id]))
                {
                    // 将存储中不在线用户删除
                    if($all_online_client_id && $client_list)
                    {
                        $all_online_client_id = array_flip($all_online_client_id);
                        $client_list = array_intersect_key($client_list, $all_online_client_id);
                    }
                    // 添加在线客户端
                    $client_list[$client_id] = $client_name;
                    // 原子添加
                    if($store->getResultCode() == \Memcached::RES_NOTFOUND)
                    {
                        $store->add($key, $client_list);
                    }
                    // 置换
                    else
                    {
                        $store->cas($cas, $key, $client_list);
                    }
                    if($store->getResultCode() == \Memcached::RES_SUCCESS)
                    {
                        return $client_list;
                    }
                }
                else 
                {
                    if($client_list[$client_id] != $client_name){
                            // 添加在线客户端
                            $client_list[$client_id] = $client_name;
                            // 原子添加
                            if($store->getResultCode() == \Memcached::RES_NOTFOUND)
                            {
                                    $store->add($key, $client_list);
                            }
                            // 置换
                            else
                            {
                                    $store->cas($cas, $key, $client_list);
                            }
                            if($store->getResultCode() == \Memcached::RES_SUCCESS)
                            {
                                    return $client_list;
                            }
                    }
                    return $client_list;
                }
            }
            throw new \Exception("addClientToRoom($live_id, $client_id, $client_name)->cas($cas, $key, \$client_list) fail .".$store->getResultMessage());
        }
        // 存储驱动是memcache或者file
        else
        {
            $handler = fopen(__FILE__, 'r');
            flock($handler,  LOCK_EX);
            $client_list = $store->get($key);
            if(!isset($client_list[$client_id]))
            {
                // 将存储中不在线用户删除
                if($all_online_client_id && $client_list)
                {
                    $all_online_client_id = array_flip($all_online_client_id);
                    $client_list = array_intersect_key($client_list, $all_online_client_id);
                }
                // 添加在线客户端
                $client_list[$client_id] = $client_name;
                $ret = $store->set($key, $client_list);
                flock($handler, LOCK_UN);
                return $client_list;
                    }else{
                                 if($client_list[$client_id] !=  $client_name){
                                         $client_list[$client_id] = $client_name;
                                         $ret = $store->set($key, $client_list);
                                         return $client_list;
                                 }
                    }

                   flock($handler, LOCK_UN);
        }
        return $client_list;
    }
    /**
     * 计算top5
     * @param $data 
     */
    public static function countFive($message, $num = 5,$ff = 0){
        global $mem;
        global $Chat_db;
//        echo "计算top5 开始\n";
//        echo 'live_id:'.$message['live_id']."\n";
//        $gifts= $Chat_db->select('gift_record.user_id,gift_record.user_icon,sum(gift_record.gift_gold) as gold')
//                ->from('gift_record')
////                ->innerJoin('`user`','`user`.id = gift_record.user_id')
//                ->where("gift_record.live_id= ".$message['live_id'])
//                ->where("gift_record.is_delete= 0")
//                ->groupBy(array('gift_record.user_id'))
//                ->orderByDESC(array('gold'))
//                ->limit($num)
//                ->query();
        $gifts = array();
        $cacheKey = self::$giftRecordKey."liveId".$message['live_id'];
        //获取缓存数据
        $cachedata = $mem->get($cacheKey);
        if(!$cachedata){
            $gifts = $Chat_db->query("SELECT sum(gift_record.gift_gold) as gold, gift_record.user_id, `user`.icon as user_icon
                                FROM gift_record
                                JOIN `user` ON `user`.id = gift_record.user_id
                                where gift_record.live_id = ".$message['live_id']."
                                GROUP BY user_id
                                ORDER BY gold DESC
                                LIMIT ".$num);

            if(!$gifts){
                echo "countFive() live_id错误或者没有记录. client_ip:{$_SERVER['REMOTE_ADDR']} time:".date("Y-m-d h:i:sa")."\n";
                return ;
            }
        }  else {
//            echo "礼物缓存\n";
            $gifts = $cachedata;
        }
//        print_r($gifts);htmlspecialchars
//        foreach ()
        //排序
//        $total = array();
//        foreach ($cachedata as $val) {
//            $total[] = $val['gold'];
//        }
//        array_multisort($total, SORT_DESC, $cachedata);
//        array_slice($cachedata,0,$num);
//        echo '排序后数组\n';
        return $gifts;
    }
    
    /**
     * 获取直播的访问数(数据库+缓存中的数)和点赞数
     * @param $data 
     */
    public static function getLiveData($liveId){
        global $mem;
        global $Chat_db;
        $cacheKey = self::$LoginDataKey;
        //获取数据库数据
        $dbData = self::getDBLiveData($liveId);
//        echo "数据库内容:\n";
//        print_r($dbData);
        $retArr = array();
        $temp = array();
        //获取缓存数据
        $cachedata = $mem->get($cacheKey);
        if($cachedata){
//            echo "有缓存记录\n";
//            print_r($cachedata);
            $flag = 0;
            foreach ($cachedata['list'] as $key=>$val){
                if($val['live_id'] == $liveId){
                    $cachedata['list'][$key]['visit_num'] = $val['visit_num'] + 1;//增加本次访问
                    $temp['visit_num'] = $val['visit_num'] + 1;
                    $flag = 1;
                    break;
                }
            }
            if($flag == 0){
//                echo "没找到内容\n";
                $val = array(
                    "live_id"=>$liveId,
                    "visit_num"=>1,
                );
                $temp['visit_num'] = 1;
                $cachedata['list'][] = $val;
            }
            $mem->Replace($cacheKey,$cachedata);
        }else{
//            echo "mei有缓存记录\n";
            $val = array(
                "live_id"=>$liveId,
                "visit_num"=>1,
            );
            $temp['visit_num'] = 1;
            $cachedata['list'][] = $val;
            $mem->add($cacheKey,$cachedata);
        }
        //返回的数据:缓存数据+数据库数据
        $retArr['visit_total'] = $temp['visit_num'] + $dbData['visit_total'];
        $retArr['set_visit_num'] = $dbData['set_visit_num'];
        $retArr['praise_total'] = $dbData['praise_total'];
        $retArr['set_praise_num'] = $dbData['set_praise_num'];
//        echo "缓存数据:".$temp['visit_num']."\n";
        echo "getLiveData()结束\n";
        return $retArr;
    }
    /**
     * 获取直播的访问数(只是数据库中的)和点赞数
     * @param $data 
     */
    public static function getDBLiveData($liveId){
        global $mem;
        global $Chat_db;
        if(!is_numeric($liveId)){
            return ;
        }
        $data = array();
        $retArr = array();
        $cacheKey = self::$LoginDBDataKey;
        $cachedata = $mem->get($cacheKey);
        if(!$cachedata){
            $live= $Chat_db->select('praise_total,visit_total,set_praise_num,set_visit_num')->from('live')->where("id= '".$liveId."'")->row();
            if(!$live){
                echo "参数错误. client_ip:{$_SERVER['REMOTE_ADDR']} time:".date("Y-m-d h:i:sa")."\n";
                return;
            }
            $data['live_id'] = $liveId;
            $data['visit_total'] = $live['visit_total'];
            $data['set_visit_num'] = $live['set_visit_num'];
            $data['praise_total'] = $live['praise_total'];
            $data['set_praise_num'] = $live['set_praise_num'];
            
            $cachedata['list'][] = $data;
            $tr = $mem->add($cacheKey, $cachedata);
//            echo "\n添加缓存成功?:".$tr."\n";
            return $data;
        }else{
            $flag = 0;
            foreach ($cachedata['list'] as $key => $val){
                if($val['live_id'] == $liveId){
                    $data['live_id'] = $liveId;
                    $data['visit_total'] = $val['visit_total'];
                    $data['set_visit_num'] = $val['set_visit_num'];
                    $data['praise_total'] = $val['praise_total'];
                    $data['set_praise_num'] = $val['set_praise_num'];
                    $flag = 1;
                    break;
                }
            }
            if($flag == 0){
                $live= $Chat_db->select('praise_total,visit_total,set_praise_num,set_visit_num')->from('live')->where("id= '".$liveId."'")->row();
                if(!$live){
                    echo "参数错误. client_ip:".$_SERVER['REMOTE_ADDR']."time:".date("Y-m-d h:i:sa")."\n";
                    return;
                }
                $data['live_id'] = $liveId;
                $data['visit_total'] = $live['visit_total'];
                $data['set_visit_num'] = $live['set_visit_num'];
                $data['praise_total'] = $live['praise_total'];
                $data['set_praise_num'] = $live['set_praise_num'];
                $cachedata['list'][] = $data;
                $tr = $mem->Replace($cacheKey, $cachedata);
//                echo "\n添加缓存成功?:".$tr."\n";
            }
        }
        return $data;
    }
        
    
}
